/*

 * Copyright (C) 2021 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package me.panpf.sketch.sample.vt.ui.listcontainer;

import me.panpf.sketch.sample.vt.ResourceTable;
import me.panpf.sketch.sample.vt.ui.listcontainer.progressindicator.AVLoadingIndicatorView;

import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;

import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;

import java.util.Date;

/**
 * ArrowRefreshHeader
 *
 * @author hw
 * @since 2021/6/23
 */
public class ArrowRefreshHeader extends DirectionalLayout implements BaseRefreshHeader {
    private static final String XR_REFRESH_KEY = "XR_REFRESH_KEY";
    private static final String XR_REFRESH_TIME_KEY = "XR_REFRESH_TIME_KEY";

    private AVLoadingIndicatorView progressView;
    private SimpleViewSwitcher mProgressBar;
    private DirectionalLayout mContainer;
    private DirectionalLayout mHeaderRefreshTimeContainer;
    private int mState = STATE_NORMAL;
    public int mMeasuredHeight;
    private String customRefreshPsKey = null;

    /**
     * destroy
     */
    public void destroy() {
        mProgressBar = null;
        if (progressView != null) {
            progressView.destroy();
            progressView = null;
        }
    }

    public ArrowRefreshHeader(Context context) {
        this(context, null, null);
    }

    public ArrowRefreshHeader(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public ArrowRefreshHeader(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        initView(context, attrSet, styleName);
    }

    /**
     * setRefreshTimeVisible
     *
     * @param show show
     */
    public void setRefreshTimeVisible(boolean show) {
        if (mHeaderRefreshTimeContainer != null) {
            mHeaderRefreshTimeContainer.setVisibility(show ? VISIBLE : HIDE);
        }
    }

    /**
     * setXrRefreshTimeKey
     *
     * @param keyName keyName
     */
    public void setXrRefreshTimeKey(String keyName) {
        if (keyName != null) {
            customRefreshPsKey = keyName;
        }
    }

    private void initView(Context context, AttrSet attrSet, String styleName) {
        LayoutScatter scatter = LayoutScatter.getInstance(context);
        mContainer = (DirectionalLayout) scatter.parse(ResourceTable.Layout_listview_header, null, false);

        mHeaderRefreshTimeContainer = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_header_refresh_time_container);
        LayoutConfig lp = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_CONTENT);
        lp.setMargins(0, 0, 0, 0);
        this.setPadding(0, 0, 0, 0);
        this.setLayoutConfig(lp);

        addComponent(mContainer, new LayoutConfig(LayoutConfig.MATCH_PARENT, 0));
        setAlignment(TextAlignment.BOTTOM);

        // init the progress view
        mProgressBar = (SimpleViewSwitcher) mContainer.findComponentById(ResourceTable.Id_listview_header_progressbar);
        progressView = new AVLoadingIndicatorView(context);
        progressView.setIndicatorColor(0xffB5B5B5);
        if (mProgressBar != null) {
            mProgressBar.setView(progressView);
            progressView.applyAnimation();
        }
        estimateSize(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        mMeasuredHeight = getEstimatedHeight();
    }

    /**
     * setProgressStyle
     *
     * @param style style
     */
    public void setProgressStyle(int style) {
        progressView = new AVLoadingIndicatorView(getContext());
        progressView.setIndicatorColor(0xffB5B5B5);
        progressView.setIndicatorId(style);
        mProgressBar.setView(progressView);
        progressView.applyAnimation();
    }

    /**
     * setIndicatorColor
     *
     * @param color color
     */
    public void setIndicatorColor(int color) {
        progressView.setIndicatorColor(color);
        this.invalidate();
    }

    /**
     * setArrowImageView
     *
     * @param resid resid
     */
    public void setArrowImageView(int resid) {
    }

    /**
     * setState
     *
     * @param state state
     */
    public void setState(int state) {
        if (state == mState) {
            return;
        }
        mState = state;
    }

    /**
     * getState
     *
     * @return mState
     */
    public int getState() {
        return mState;
    }

    private long getLastRefreshTime() {
        String spKeyName = XR_REFRESH_KEY;
        if (customRefreshPsKey != null) {
            spKeyName = customRefreshPsKey;
        }
        DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
        Preferences preferences = databaseHelper.getPreferences(spKeyName);
        return preferences.getLong(XR_REFRESH_TIME_KEY, new Date().getTime());

    }

    private void saveLastRefreshTime(long refreshTime) {
        String spKeyName = XR_REFRESH_KEY;
        if (customRefreshPsKey != null) {
            spKeyName = customRefreshPsKey;
        }
        DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
        Preferences preferences = databaseHelper.getPreferences(spKeyName);
        preferences.putLong(XR_REFRESH_TIME_KEY, refreshTime).flush();
    }

    @Override
    public void refreshComplete() {
        saveLastRefreshTime(System.currentTimeMillis());
        setState(STATE_DONE);
        reset();
    }

    /**
     * setVisibleHeight
     *
     * @param height height
     */
    public void setVisibleHeight(int height) {
        if (height <= 0) {
            height = 0;
        } else if (height > 400) {
            height = 400;
        }
        LayoutConfig lp = (LayoutConfig) mContainer.getLayoutConfig();
        lp.height = height;
        mContainer.setLayoutConfig(lp);
    }

    /**
     * getVisibleHeight
     *
     * @return height
     */
    public int getVisibleHeight() {
        LayoutConfig lp = (LayoutConfig) mContainer.getLayoutConfig();
        return lp.height;
    }

    @Override
    public void onMove(float delta) {
        if (getVisibleHeight() > 0 || delta > 0) {
            setVisibleHeight((int) delta);
            if (mState <= STATE_RELEASE_TO_REFRESH) {   // 未处于刷新状态，更新箭头
                if (getVisibleHeight() > mMeasuredHeight) {
                    setState(STATE_RELEASE_TO_REFRESH);
                } else {
                    setState(STATE_NORMAL);
                }
            }
        }
    }

    @Override
    public boolean releaseAction() {
        boolean isOnRefresh = false;
        int height = getVisibleHeight();
        if (height == 0) {
            isOnRefresh = false;
        }

        if (getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING) {
            setState(STATE_REFRESHING);
            isOnRefresh = true;
        }
        if (mState != STATE_REFRESHING) {
            smoothScrollTo(0);
        }

        if (mState == STATE_REFRESHING) {
            int destHeight = mMeasuredHeight;
            setVisibleHeight(destHeight);
        }
        return isOnRefresh;
    }

    /**
     * reset
     */
    public void reset() {
        smoothScrollTo(0);
        setState(STATE_NORMAL);
    }

    private void smoothScrollTo(int destHeight) {
        setVisibleHeight(0);
        postLayout();
        invalidate();
    }

    /**
     * friendlyTime
     *
     * @param time time
     * @return friendlyTime
     */
    public static String friendlyTime(Date time) {
        return friendlyTime(time.getTime());
    }

    /**
     * friendlyTime
     *
     * @param time time
     * @return friendlyTime
     */
    public static String friendlyTime(long time) {
        // 获取time距离当前的秒数
        int ct = (int) ((System.currentTimeMillis() - time) / 1000);

        if (ct == 0) {
            return "刚刚";
        }

        if (ct > 0 && ct < 60) {
            return ct + "秒前";
        }

        if (ct >= 60 && ct < 3600) {
            return Math.max(ct / 60, 1) + "分钟前";
        }
        if (ct >= 3600 && ct < 86400) {
            return ct / 3600 + "小时前";
        }
        if (ct >= 86400 && ct < 2592000) { // 86400 * 30
            int day = ct / 86400;
            return day + "天前";
        }
        if (ct >= 2592000 && ct < 31104000) { // 86400 * 30
            return ct / 2592000 + "月前";
        }
        return ct / 31104000 + "年前";
    }
}
